#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#include<iostream>
#include<cstring>
#include<string.h>
#include<unistd.h>
using namespace std;

void Usage(string proc)
{
    cout << "Usage: " << proc << "server_ip server_port" << endl;
}

// ./client_tcp server_ip server_port
int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        return 1;
    }
    string svr_ip = argv[1];
    uint16_t svr_port = atoi(argv[2]);
    //1.socket创建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0)
    {
        cout << "client socket err" << endl;
        return 2;
    }

    //2.client无需显示bind(也是需要bind的)什么时候?connect的时候
    // 永远都是client主动去连接server，server是被动地，所以server不知道client什么时候来，
    // 故，server必须不间断的listen，而client不需要listen，也就无需accept了
    // 那client关心什么? connect连接服务器！

    //3.connect连接服务器
    struct sockaddr_in server;
    bzero(&server, sizeof(server));//清空结构体变量
    //inet_addr 函数做两件事：1.点分十进制IP ---> 四字节IP  2.由主机序列转化为网络序列
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(svr_ip.c_str());
    server.sin_port = htons(svr_port);
    //通过sock套接字连接server端
    if(connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0)
    {
        cout << "client connect err" << endl;
        return 3;
    }
    cout << "connect success!" << endl;

    //4.进行正常的业务请求
    while(true)
    {
        cout << "Please Entre# ";
        char buffer[1024];
        //读取用户输入，放到buffer里
        fgets(buffer, sizeof(buffer)-1, stdin);
        //将buffer里的数据通过sock套接字发送给server端
        write(sock, buffer, strlen(buffer));
        //通过sock套接字读取server传过来的信息处理结果并放到buffer里
        ssize_t s = read(sock, buffer, sizeof(buffer)-1);
        if(s > 0)
        {
            //当作字符串看待
            buffer[s] = 0;
            //输出server端的信息处理结果
            cout << "server echo# " << buffer << endl;
        }
    }
    return 0;
}
